{
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "dcQ6l8DrzJad"
      },
      "source": [
        "##### Copyright 2020 Google"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 1,
      "metadata": {
        "cellView": "form",
        "id": "7GiJJW7KzLLA"
      },
      "outputs": [],
      "source": [
        "#@title Licensed under the Apache License, Version 2.0 (the \"License\");\n",
        "# you may not use this file except in compliance with the License.\n",
        "# You may obtain a copy of the License at\n",
        "#\n",
        "# https://www.apache.org/licenses/LICENSE-2.0\n",
        "#\n",
        "# Unless required by applicable law or agreed to in writing, software\n",
        "# distributed under the License is distributed on an \"AS IS\" BASIS,\n",
        "# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n",
        "# See the License for the specific language governing permissions and\n",
        "# limitations under the License."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "Iznv7pW1yzWA"
      },
      "source": [
        "# QAOA Tasks"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "UX6Wn1flzYOg"
      },
      "source": [
        "<table class=\"tfo-notebook-buttons\" align=\"left\">\n",
        "  <td>\n",
        "    <a target=\"_blank\" href=\"https://www.example.org/cirq/experiments/qaoa/tasks\"><img src=\"https://www.tensorflow.org/images/tf_logo_32px.png\" />View on QuantumLib</a>\n",
        "  </td>\n",
        "  <td>\n",
        "    <a target=\"_blank\" href=\"https://colab.research.google.com/github/quantumlib/ReCirq/blob/master/docs/qaoa/tasks.ipynb\"><img src=\"https://www.tensorflow.org/images/colab_logo_32px.png\" />Run in Google Colab</a>\n",
        "  </td>\n",
        "  <td>\n",
        "    <a target=\"_blank\" href=\"https://github.com/quantumlib/ReCirq/blob/master/docs/qaoa/tasks.ipynb\"><img src=\"https://www.tensorflow.org/images/GitHub-Mark-32px.png\" />View source on GitHub</a>\n",
        "  </td>\n",
        "  <td>\n",
        "    <a href=\"https://storage.googleapis.com/tensorflow_docs/ReCirq/docs/qaoa/tasks.ipynb\"><img src=\"https://www.tensorflow.org/images/download_logo_32px.png\" />Download notebook</a>\n",
        "  </td>\n",
        "</table>"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "ODiWjvdR0A-c"
      },
      "source": [
        "## Setup\n",
        "\n",
        "Install the ReCirq package:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 2,
      "metadata": {
        "id": "CNcvxXPs0Buy"
      },
      "outputs": [],
      "source": [
        "try:\n",
        "    import recirq\n",
        "except ImportError:\n",
        "    !pip install git+https://github.com/quantumlib/ReCirq"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "7EyHaU6p0Ebv"
      },
      "source": [
        "And import ReCirq:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 3,
      "metadata": {
        "id": "hJC1Mqt00Txt"
      },
      "outputs": [],
      "source": [
        "import recirq"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "L2vg1-UXyzWC"
      },
      "source": [
        "## Problem generation\n",
        "\n",
        "First, we generate and save all of the random instances of the problem. This is not computationally intensive but very important to do first so we have a fixed set of random instances."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 4,
      "metadata": {
        "id": "_ljoY33fyzWD"
      },
      "outputs": [
        {
          "data": {
            "text/markdown": [
              "### HardwareGridProblemGenerationTask\n",
              "Generate 'Hardware Grid' problems for a named device.\n",
              "\n",
              "This is a subgraph of the device's hardware topology with random\n",
              "+-1 weights on edges.\n",
              "\n",
              "#### See Also\n",
              "`generate_hardware_grid_problem` \n",
              "\n",
              "#### Attributes\n",
              " - `dataset_id`: A unique identifier for this dataset.\n",
              " - `device_name`: The device to generate problems for.\n",
              " - `instance_i`: Generate random instances indexed by this number.\n",
              " - `n_qubits`: Generate an n-qubit instance.\n"
            ],
            "text/plain": [
              "<IPython.core.display.Markdown object>"
            ]
          },
          "execution_count": 4,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "from recirq.qaoa.experiments.problem_generation_tasks import \\\n",
        "    SKProblemGenerationTask, HardwareGridProblemGenerationTask, ThreeRegularProblemGenerationTask, \\\n",
        "    generate_3_regular_problem, generate_sk_problem, generate_hardware_grid_problem\n",
        "\n",
        "pgen_dataset_id = '2020-03-tutorial'\n",
        "hardware_grid_problem_tasks = [\n",
        "    HardwareGridProblemGenerationTask(\n",
        "        dataset_id=pgen_dataset_id,\n",
        "        device_name='Sycamore23',\n",
        "        instance_i=i,\n",
        "        n_qubits=n\n",
        "    )\n",
        "    for i in range(5)\n",
        "    for n in range(2, 8 + 1, 2)\n",
        "]\n",
        "recirq.display_markdown_docstring(HardwareGridProblemGenerationTask)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 5,
      "metadata": {
        "id": "1o5-pazdyzWH"
      },
      "outputs": [
        {
          "data": {
            "text/markdown": [
              "### SKProblemGenerationTask\n",
              "Generate a Sherrington-Kirkpatrick problem.\n",
              "\n",
              "This is a complete (fully-connected) graph with random +-1\n",
              "weights on edges.\n",
              "\n",
              "#### See Also\n",
              "`generate_sk_problem` \n",
              "\n",
              "#### Attributes\n",
              " - `dataset_id`: A unique identifier for this dataset.\n",
              " - `instance_i`: Generate random instances indexed by this number.\n",
              " - `n_qubits`: Generate an n-qubit instance.\n"
            ],
            "text/plain": [
              "<IPython.core.display.Markdown object>"
            ]
          },
          "execution_count": 5,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "sk_problem_tasks = [\n",
        "    SKProblemGenerationTask(\n",
        "        dataset_id=pgen_dataset_id,\n",
        "        instance_i=i,\n",
        "        n_qubits=n\n",
        "    )\n",
        "    for i in range(5)\n",
        "    for n in range(3, 7 + 1, 2)\n",
        "]\n",
        "recirq.display_markdown_docstring(SKProblemGenerationTask)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 6,
      "metadata": {
        "id": "qyiL_W_KyzWK"
      },
      "outputs": [],
      "source": [
        "three_regular_problem_tasks = [\n",
        "    ThreeRegularProblemGenerationTask(\n",
        "        dataset_id=pgen_dataset_id,\n",
        "        instance_i=i,\n",
        "        n_qubits=n\n",
        "    )\n",
        "    for i in range(5)\n",
        "    for n in range(3, 8 + 1) if 3 * n % 2 == 0\n",
        "]"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "bMBE4_hWyzWO"
      },
      "source": [
        "### Run the tasks"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "EYmmjjRnyzWO"
      },
      "outputs": [],
      "source": [
        "for task in hardware_grid_problem_tasks:\n",
        "    generate_hardware_grid_problem(task)\n",
        "for task in sk_problem_tasks:\n",
        "    generate_sk_problem(task)\n",
        "for task in three_regular_problem_tasks:\n",
        "    generate_3_regular_problem(task)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "JxNchpctyzWR"
      },
      "source": [
        "## Angle precomputation"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 8,
      "metadata": {
        "id": "G0eSk61UyzWR"
      },
      "outputs": [
        {
          "data": {
            "text/markdown": [
              "### AnglePrecomputationTask\n",
              "Pre-compute optimized angles classically for a given problem.\n",
              "\n",
              "#### See Also\n",
              "`precompute_angles` \n",
              "\n",
              "#### Attributes\n",
              " - `dataset_id`: A unique identifier for this dataset.\n",
              " - `generation_task`: The input task which specifies the problem.\n",
              " - `p`: QAOA depth hyperparameter p. The number of parameters is 2*p.\n"
            ],
            "text/plain": [
              "<IPython.core.display.Markdown object>"
            ]
          },
          "execution_count": 8,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "from recirq.qaoa.experiments.angle_precomputation_tasks import \\\n",
        "    AnglePrecomputationTask, precompute_angles\n",
        "\n",
        "apre_dataset_id = '2020-03-tutorial'\n",
        "precompute_tasks = [\n",
        "    AnglePrecomputationTask(\n",
        "        dataset_id=apre_dataset_id,\n",
        "        generation_task=gen_task,\n",
        "        p=p)\n",
        "    for gen_task in recirq.roundrobin(\n",
        "        hardware_grid_problem_tasks,\n",
        "        sk_problem_tasks,\n",
        "        three_regular_problem_tasks,\n",
        "    )\n",
        "    for p in range(1, 3 + 1)\n",
        "]\n",
        "recirq.display_markdown_docstring(AnglePrecomputationTask)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "9TICgyjByzWU"
      },
      "outputs": [],
      "source": [
        "for task in precompute_tasks:\n",
        "    precompute_angles(task)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "U-4ZhSe_yzWX"
      },
      "source": [
        "## Precomputed angle data collection"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 10,
      "metadata": {
        "id": "yxAV6GjWyzWY"
      },
      "outputs": [
        {
          "data": {
            "text/markdown": [
              "### PrecomputedDataCollectionTask\n",
              "PrecomputedDataCollectionTask(dataset_id: str, precomputation_task: recirq.qaoa.experiments.angle_precomputation_tasks.AnglePrecomputationTask, device_name: str, n_shots: int, structured: bool = False, echoed: bool = False)"
            ],
            "text/plain": [
              "<IPython.core.display.Markdown object>"
            ]
          },
          "execution_count": 10,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "from recirq.qaoa.experiments.precomputed_execution_tasks import \\\n",
        "    PrecomputedDataCollectionTask, collect_data\n",
        "    \n",
        "\n",
        "dcol_dataset_id = '2020-03-tutorial'\n",
        "data_collection_tasks = [\n",
        "    PrecomputedDataCollectionTask(\n",
        "        dataset_id=dcol_dataset_id,\n",
        "        precomputation_task=pre_task,\n",
        "        device_name='Syc23-simulator',\n",
        "        n_shots=50_000,\n",
        "        structured=True,\n",
        "    )\n",
        "    for pre_task in precompute_tasks\n",
        "]\n",
        "recirq.display_markdown_docstring(PrecomputedDataCollectionTask)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "F5oIYM1GyzWb"
      },
      "outputs": [],
      "source": [
        "await recirq.execute_in_queue(collect_data, data_collection_tasks, num_workers=2)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "ZR4uOP5SyzWe"
      },
      "source": [
        "## Landscape data collection"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 12,
      "metadata": {
        "id": "9fx1_PF5yzWe"
      },
      "outputs": [
        {
          "data": {
            "text/markdown": [
              "### P1LandscapeDataCollectionTask\n",
              "Collect data for a p=1 landscape\n",
              "\n",
              "This task does exactly one (beta, gamma) point. You will have\n",
              "to run many of these tasks to get a full landscape\n",
              "\n",
              "#### See Also\n",
              "`collect_p1_landscape_data` \n",
              "\n",
              "#### Attributes\n",
              " - `dataset_id`: A unique identifier for this dataset.\n",
              " - `generation_task`: The task specifying the problem to collect data for\n",
              " - `device_name`: The device to run on\n",
              " - `n_shots`: The number of shots to take\n",
              " - `gamma`: The problem unitary parameter gamma\n",
              " - `beta`: The driver unitary parameter beta\n",
              " - `line_placement_strategy`: Only used for SK model problems. Options include 'brute_force', 'random', 'greedy', 'anneal', 'mst', and 'mixed'.\n"
            ],
            "text/plain": [
              "<IPython.core.display.Markdown object>"
            ]
          },
          "execution_count": 12,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "from recirq.qaoa.experiments.p1_landscape_tasks import \\\n",
        "    P1LandscapeDataCollectionTask, \\\n",
        "    get_data_collection_tasks_on_a_grid, \\\n",
        "    collect_either_landscape_or_cal\n",
        "\n",
        "recirq.display_markdown_docstring(P1LandscapeDataCollectionTask)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "XlcHhXUwyzWh"
      },
      "outputs": [],
      "source": [
        "hardware_grid_problem_task = HardwareGridProblemGenerationTask(\n",
        "    dataset_id=pgen_dataset_id,\n",
        "    device_name='Sycamore23',\n",
        "    instance_i=0,\n",
        "    n_qubits=4\n",
        ")\n",
        "data_collection_tasks = get_data_collection_tasks_on_a_grid(\n",
        "    pgen_task=hardware_grid_problem_task,\n",
        "    dataset_id=dcol_dataset_id,\n",
        "    gamma_res=11,\n",
        "    beta_res=11,\n",
        "    device_name='Syc23-simulator',\n",
        "    epoch=\"grid\")\n",
        "\n",
        "await recirq.execute_in_queue(collect_either_landscape_or_cal,\n",
        "                              data_collection_tasks,\n",
        "                              num_workers=2)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "FTxZFYPLyzWj"
      },
      "outputs": [],
      "source": [
        "sk_problem_task = SKProblemGenerationTask(\n",
        "    dataset_id=pgen_dataset_id,\n",
        "    instance_i=0,\n",
        "    n_qubits=3,\n",
        ")\n",
        "data_collection_tasks = get_data_collection_tasks_on_a_grid(\n",
        "    pgen_task=sk_problem_task,\n",
        "    dataset_id=dcol_dataset_id,\n",
        "    gamma_res=11,\n",
        "    beta_res=11,\n",
        "    device_name='Syc23-simulator',\n",
        "    epoch=\"sk\")\n",
        "await recirq.execute_in_queue(collect_either_landscape_or_cal,\n",
        "                              data_collection_tasks,\n",
        "                              num_workers=2)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "Rq1ePbzQyzWm"
      },
      "outputs": [],
      "source": [
        "three_regular_problem_task = ThreeRegularProblemGenerationTask(\n",
        "    dataset_id=pgen_dataset_id,\n",
        "    instance_i=0,\n",
        "    n_qubits=4\n",
        ")\n",
        "data_collection_tasks = get_data_collection_tasks_on_a_grid(\n",
        "    pgen_task=three_regular_problem_task,\n",
        "    dataset_id=dcol_dataset_id,\n",
        "    device_name='Syc23-simulator',\n",
        "    gamma_res=11,\n",
        "    beta_res=11,\n",
        "    epoch=\"tr\")\n",
        "\n",
        "await recirq.execute_in_queue(collect_either_landscape_or_cal,\n",
        "                              data_collection_tasks,\n",
        "                              num_workers=2)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "be4b07cfe483"
      },
      "source": [
        "## Optimization Data Collection"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "9f21aa53f6ce"
      },
      "outputs": [],
      "source": [
        "from recirq.qaoa.experiments.optimization_tasks import \\\n",
        "    OptimizationAlgorithm, \\\n",
        "    OptimizationTask, \\\n",
        "    collect_optimization_data\n",
        "\n",
        "recirq.display_markdown_docstring(OptimizationTask)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "b93b6c7817c7"
      },
      "outputs": [],
      "source": [
        "optimization_algorithm = OptimizationAlgorithm(\n",
        "    method='MGD',\n",
        "    n_shots=25000,\n",
        "    options={\n",
        "        'max_iterations': 10,\n",
        "        'rate': 0.3,\n",
        "        'sample_radius': 0.1,\n",
        "        'n_sample_points_ratio': 1.0,\n",
        "        'rate_decay_exponent': 0.4,\n",
        "        'stability_constant': 250,\n",
        "        'sample_radius_decay_exponent': 0.08,\n",
        "    })\n",
        "hardware_grid_optimization_task = OptimizationTask(\n",
        "    dataset_id=dcol_dataset_id,\n",
        "    generation_task=hardware_grid_problem_task,\n",
        "    device_name='Syc23-simulator',\n",
        "    p=1,\n",
        "    algorithm=optimization_algorithm,\n",
        "    x0=[0.3, 0.2])\n",
        "\n",
        "collect_optimization_data(hardware_grid_optimization_task)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "0b49a2b9de9b"
      },
      "outputs": [],
      "source": [
        "optimization_algorithm = OptimizationAlgorithm(\n",
        "    method='MGD',\n",
        "    n_shots=25000,\n",
        "    options={\n",
        "        'max_iterations': 10,\n",
        "        'rate': 0.3,\n",
        "        'sample_radius': 0.1,\n",
        "        'n_sample_points_ratio': 1.0,\n",
        "        'rate_decay_exponent': 0.3,\n",
        "        'stability_constant': 200,\n",
        "        'sample_radius_decay_exponent': 0.08,\n",
        "    })\n",
        "sk_optimization_task = OptimizationTask(\n",
        "    dataset_id=dcol_dataset_id,\n",
        "    generation_task=sk_problem_task,\n",
        "    device_name='Syc23-simulator',\n",
        "    p=1,\n",
        "    algorithm=optimization_algorithm,\n",
        "    x0=[0.3, 0.2])\n",
        "\n",
        "collect_optimization_data(sk_optimization_task)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "1b15ac1a9915"
      },
      "outputs": [],
      "source": [
        "optimization_algorithm = OptimizationAlgorithm(\n",
        "    method='MGD',\n",
        "    n_shots=25000,\n",
        "    options={\n",
        "        'max_iterations': 10,\n",
        "        'rate': 0.2,\n",
        "        'sample_radius': 0.1,\n",
        "        'n_sample_points_ratio': 1.0,\n",
        "        'rate_decay_exponent': 0.4,\n",
        "        'stability_constant': 250,\n",
        "        'sample_radius_decay_exponent': 0.08,\n",
        "    })\n",
        "three_regular_optimization_task = OptimizationTask(\n",
        "    dataset_id=dcol_dataset_id,\n",
        "    generation_task=three_regular_problem_task,\n",
        "    device_name='Syc23-simulator',\n",
        "    p=1,\n",
        "    algorithm=optimization_algorithm,\n",
        "    x0=[0.3, 0.2])\n",
        "\n",
        "collect_optimization_data(three_regular_optimization_task)"
      ]
    }
  ],
  "metadata": {
    "colab": {
      "name": "tasks.ipynb",
      "toc_visible": true
    },
    "kernelspec": {
      "display_name": "Python 3",
      "name": "python3"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}
